extends Node
class_name SoundManager

# Sound buses
var master_volume: float = 1.0
var sfx_volume: float = 0.8
var music_volume: float = 0.6

# Sound players
var sfx_players: Array[AudioStreamPlayer3D] = []
var music_player: AudioStreamPlayer
var ui_sound_player: AudioStreamPlayer

# Sound library (we'll use generated tones for now)
var sounds = {}

func _ready():
	# Create music player
	music_player = AudioStreamPlayer.new()
	music_player.bus = "Music"
	music_player.volume_db = linear_to_db(music_volume)
	add_child(music_player)
	
	# Create UI sound player
	ui_sound_player = AudioStreamPlayer.new()
	ui_sound_player.bus = "UI"
	ui_sound_player.volume_db = linear_to_db(sfx_volume)
	add_child(ui_sound_player)
	
	# Create pool of 3D sound players
	for i in range(10):
		var player = AudioStreamPlayer3D.new()
		player.bus = "SFX"
		player.volume_db = linear_to_db(sfx_volume)
		player.max_distance = 50
		player.attenuation_model = AudioStreamPlayer3D.ATTENUATION_INVERSE_DISTANCE
		add_child(player)
		sfx_players.append(player)
	
	# Generate placeholder sounds
	generate_sounds()

func generate_sounds():
	# Attack sound
	var attack_sound = AudioStreamGenerator.new()
	attack_sound.mix_rate = 44100
	sounds["attack"] = attack_sound
	
	# Ability sounds
	var ability_sound = AudioStreamGenerator.new()
	ability_sound.mix_rate = 44100
	sounds["ability"] = ability_sound
	
	# UI sounds
	var click_sound = AudioStreamGenerator.new()
	click_sound.mix_rate = 44100
	sounds["click"] = click_sound
	
	var purchase_sound = AudioStreamGenerator.new()
	purchase_sound.mix_rate = 44100
	sounds["purchase"] = purchase_sound
	
	# Round sounds
	var round_start = AudioStreamGenerator.new()
	round_start.mix_rate = 44100
	sounds["round_start"] = round_start
	
	var victory_sound = AudioStreamGenerator.new()
	victory_sound.mix_rate = 44100
	sounds["victory"] = victory_sound

func play_3d_sound(sound_name: String, position: Vector3, volume: float = 1.0):
	var player = get_available_3d_player()
	if player and sound_name in sounds:
		player.stream = sounds[sound_name]
		player.global_position = position
		player.volume_db = linear_to_db(sfx_volume * volume)
		player.pitch_scale = randf_range(0.9, 1.1)  # Slight variation
		player.play()

func play_ui_sound(sound_name: String, volume: float = 1.0):
	if ui_sound_player and sound_name in sounds:
		ui_sound_player.stream = sounds[sound_name]
		ui_sound_player.volume_db = linear_to_db(sfx_volume * volume)
		ui_sound_player.pitch_scale = 1.0
		ui_sound_player.play()

func play_music(music_name: String, fade_in: bool = true):
	if not music_player:
		return
	
	if fade_in:
		music_player.volume_db = -80
		music_player.play()
		var tween = get_tree().create_tween()
		tween.tween_property(music_player, "volume_db", linear_to_db(music_volume), 2.0)
	else:
		music_player.volume_db = linear_to_db(music_volume)
		music_player.play()

func stop_music(fade_out: bool = true):
	if not music_player:
		return
	
	if fade_out:
		var tween = get_tree().create_tween()
		tween.tween_property(music_player, "volume_db", -80, 1.0)
		tween.tween_callback(music_player.stop)
	else:
		music_player.stop()

func get_available_3d_player() -> AudioStreamPlayer3D:
	for player in sfx_players:
		if not player.playing:
			return player
	return sfx_players[0]  # Reuse first if all are playing

func set_master_volume(value: float):
	master_volume = clamp(value, 0.0, 1.0)
	AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear_to_db(master_volume))

func set_sfx_volume(value: float):
	sfx_volume = clamp(value, 0.0, 1.0)
	AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), linear_to_db(sfx_volume))

func set_music_volume(value: float):
	music_volume = clamp(value, 0.0, 1.0)
	AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear_to_db(music_volume))

# Sound effect helpers
func play_attack_sound(position: Vector3):
	play_3d_sound("attack", position, 0.7)

func play_ability_sound(position: Vector3):
	play_3d_sound("ability", position, 1.0)

func play_purchase_sound():
	play_ui_sound("purchase", 1.0)

func play_click_sound():
	play_ui_sound("click", 0.5)

func play_round_start():
	play_ui_sound("round_start", 1.0)

func play_victory():
	play_ui_sound("victory", 1.2)